package com.atguigu.mybatisplus.service.impl;
import com.atguigu.mybatisplus.mapper.UserMapper;

import com.atguigu.mybatisplus.model.entity.Dept;
import com.atguigu.mybatisplus.model.entity.User;

import com.atguigu.mybatisplus.model.form.UserForm;

import com.atguigu.mybatisplus.model.query.UserPageQuery;
import com.atguigu.mybatisplus.model.vo.DataUserPageVO;
import com.atguigu.mybatisplus.model.vo.UserPageVo;
import com.atguigu.mybatisplus.service.DeptService;
import com.atguigu.mybatisplus.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.lang.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private DeptService deptService;

    /**
     * 用户分页列表
     *
     * @param sysUserPageQuery
     * @return
     */
    @Override
    public DataUserPageVO getUserPage(UserPageQuery sysUserPageQuery) {
        // 初始化分页参数
        Long pageNum = sysUserPageQuery.getPageNum();
        Long pageSize = sysUserPageQuery.getPageSize();
        IPage<User> page = new Page<>(pageNum, pageSize);
        // 构造查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        // 关键字模糊查询(用户名、昵称、手机号)
        String keywords = sysUserPageQuery.getKeywords();
        if (StringUtils.isNotBlank(keywords)) {
            queryWrapper
                    .like(User::getUsername, keywords)
                    .or()
                    .like(User::getNickname, keywords)
                    .or()
                    .like(User::getMobile, keywords);
        }
        // 状态精准查询
        Integer status = sysUserPageQuery.getStatus();
        if (status != null) {
            queryWrapper.eq(User::getStatus, status);
        }
        // 创建时间范围查询
        List<String> createTime = sysUserPageQuery.getCreateTime();
        if (createTime != null && createTime.size() == 2) {
            queryWrapper.between(User::getCreateTime, createTime.get(0), createTime.get(1));
        }
        // 执行分页查询
        IPage<User> userIPage = userMapper.selectPage(page, queryWrapper);
        // 实体对象转换为VO
        List<User> records = userIPage.getRecords();
        List<UserPageVo> userPageVoList = new ArrayList<>();
        for (User record : records) {
            UserPageVo userPageVo = new UserPageVo();
            BeanUtils.copyProperties(record, userPageVo);
            userPageVoList.add(userPageVo);
        }
        // 构建并返回最终分页结果
        DataUserPageVO dataUserPageVO = new DataUserPageVO();
        dataUserPageVO.setList(userPageVoList);
        dataUserPageVO.setTotal(userIPage.getTotal());
        return dataUserPageVO;
    }

    /**
     * 用户新增
     *
     * @param userForm
     */
    @Override
    @Transactional
    public void saveUser(UserForm userForm) {
        // 新增用户时，角色不能为空
        List<Long> roleIds = userForm.getRoleIds();
        if (roleIds == null || roleIds.isEmpty()) {
            throw new IllegalArgumentException("用户角色不能为空");
        }


        User user = new User();
        BeanUtils.copyProperties(userForm, user);
        // 设置默认密码并加密存储
        user.setPassword(passwordEncoder.encode("123456"));
        user.setCreateTime(LocalDateTime.now());
        user.setCreateBy(1L);
        user.setUpdateTime(LocalDateTime.now());
        user.setUpdateBy(1L);
        userMapper.insert(user);
    }

    /**
     * 修改用户
     *
     * @param userId
     * @param userForm
     */
    @Override
    public void updateUserById(Long userId, UserForm userForm) {
        // 防止ID篡改校验
        if (!userId.equals(userForm.getId())) {
            throw new IllegalArgumentException("表单的ID与路径参数不一致");
        }
        // 用户名唯一性效验
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
                .eq(User::getUsername, userForm.getUsername())
                .ne(User::getId, userId);
        Long count = userMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new IllegalArgumentException("用户名已存在，请重新输入");
        }
        // 查询原用户信息，保留未修改的属性
        User user = userMapper.selectById(userId);
        Assert.notNull(user, "用户不存在");
        // TODO 角色信息
        // 拷贝表单数据到实体
        BeanUtils.copyProperties(userForm, user);
        userMapper.updateById(user);
    }

    /**
     * 用户表单数据
     *
     * @param userId
     * @return
     */
    @Override
    public UserForm getUserFormById(Long userId) {
        User user = userMapper.selectById(userId);
        UserForm userForm = new UserForm();
        BeanUtils.copyProperties(user, userForm);
        return userForm;
    }

    /**
     * 重置用户密码
     *
     * @param userId
     * @param password
     */
    @Override
    public void updatePassword(Long userId, String password) {
        User user = userMapper.selectById(userId);
        // 校验用户是否存在
        Assert.notNull(user, "用户不存在");
        // 校验密码是否为空
        Assert.hasText(password, "密码不能为空");
        // 校验密码长度
        Assert.isTrue(password.length() >= 6, "密码长度不能小于6位");
        // 校验密码是否与原密码相同
        Assert.isTrue(!passwordEncoder.matches(password, user.getPassword()), "新密码不能与原密码相同");
        user.setPassword(passwordEncoder.encode(password));
        userMapper.updateById(user);
    }

    /**
     * 用户状态更新
     *
     * @param userId
     * @param status
     */
    @Override
    public void updateStatus(Long userId, Integer status) {
        User user = userMapper.selectById(userId);
        // 校验用户是否存在
        Assert.notNull(user, "用户不存在");
        // 校验状态是否有效
        Assert.isTrue(status == 0 || status == 1, "状态值无效");
        user.setStatus(status);
        userMapper.updateById(user);
    }
}
